// 图片上传组件（支持单图/多图切换 + 弹窗预览）
import React, { useState, useMemo } from 'react';
import { Upload, message, UploadFile, UploadProps, Image } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { pictureApi } from '@/api/url/index';

/* 接口响应类型定义*/
interface ApiResponse {
  code: number;
  msg: string;
  time: string;
  data: {
    fullurl: string; // 接口直接返回完整URL
    url: string;     // 相对路径
  };
}

/** 组件属性类型定义 */
interface ImageUploaderProps {
  /** 初始图片URL（单图字符串/多图数组） */
  imageUrl?: string | string[];
  /** 上传成功回调（返回处理后的URL） */
  onUploadSuccess: (fullUrl: string | string[]) => void;
  /** 接受的文件类型（默认：image/*） */
  accept?: string;
  /** 最大上传数量（1=单图[单选]，>1=多图[多选]，默认：1） */
  maxCount?: number;
  /** 预览图片尺寸（默认：80px，适配表格） */
  previewSize?: number;
}

/**
 * 图片上传组件
 * @description 单图单选/多图多选自动切换、弹窗预览、删除、大小限制（5MB）
 */
const ImageUploader: React.FC<ImageUploaderProps> = ({
  imageUrl = '',
  onUploadSuccess,
  accept = 'image/*',
  maxCount = 1,    // 1=单图（单选），>1=多图（多选）
  previewSize = 50,
}) => {
  // 初始化文件列表
  const [fileList, setFileList] = useState<UploadFile[]>(() => {
    if (!imageUrl) return [];
    const urlList = Array.isArray(imageUrl) ? imageUrl : [imageUrl];
    return urlList.map((url, index) => ({
      uid: `preview-${index}-${Date.now()}`,
      name: url.split('/').pop() || `image-${index + 1}.jpg`,
      status: 'done' as const,
      url: url,
      response: { data: { fullurl: url } }
    }));
  });

  // 预览弹窗控制
  const [previewVisible, setPreviewVisible] = useState(false);
  const [currentPreviewUrl, setCurrentPreviewUrl] = useState('');

  /** 类型守卫：判断是否为合法接口响应 */
  const isApiResponse = (res: unknown): res is ApiResponse => {
    return Boolean(
      (res as ApiResponse)?.code !== undefined &&
      (res as ApiResponse)?.msg !== undefined &&
      (res as ApiResponse)?.data?.fullurl !== undefined
    );
  };

  /** 处理文件上传逻辑 */
  const handleUpload = async (file: File): Promise<string> => {
    if (file.size / 1024 / 1024 > 5) {
      message.error('文件大小不能超过5MB');
      throw new Error('文件大小超过限制');
    }
    const formData = new FormData();
    formData.append('file', file);

    try {
      const res = await pictureApi().signIn(formData);
      const response = isApiResponse(res) ? res : (res as { data: ApiResponse })?.data;
      if (!isApiResponse(response) || response.code !== 1 || !response.data?.fullurl) {
        throw new Error(response?.msg || '上传失败：接口响应异常');
      }
      const fullUrl = response.data.fullurl;
      return fullUrl;
    } catch (err) {
      const errorMsg = err instanceof Error ? err.message : '网络错误，请重试';
      message.error(errorMsg);
      throw err;
    }
  };

  /** 文件列表变化回调 */
  const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
    setFileList(newFileList);
    const doneUrls = newFileList
      .filter(file => file.status === 'done')
      .map(file => {
        if (file.response?.data?.fullurl) return file.response.data.fullurl;
        if (file.url) return file.url;
        if (file.response?.fullurl) return file.response.fullurl;
        return '';
      })
      .filter(url => url !== '');
    // 单图返回字符串，多图返回数组
    const resultUrl = maxCount === 1 ? doneUrls[0] || '' : doneUrls;
    onUploadSuccess(resultUrl);
  };

  /** 自定义上传请求 */
  const customRequest: UploadProps['customRequest'] = async (options) => {
    const { file, onProgress, onSuccess, onError } = options;
    try {
      onProgress?.({ percent: 0 });
      const fullUrl = await handleUpload(file as File);
      onProgress?.({ percent: 100 });
      onSuccess?.({
        code: 1,
        msg: '上传成功',
        data: { fullurl: fullUrl, url: fullUrl.split('/').pop() || fullUrl }
      });
    } catch (error) {
      console.error('上传失败:', error);
      onError?.(error as Error);
    }
  };

  /** 处理预览：打开弹窗 */
  const handlePreview = (file: UploadFile) => {
    const previewUrl = file.response?.data?.fullurl || file.url || '';
    if (previewUrl) {
      setCurrentPreviewUrl(previewUrl);
      setPreviewVisible(true);
    }
  };

  /** 控制上传按钮显示状态 */
  const showUploadBtn = useMemo(() => {
    const doneFileCount = fileList.filter(file => file.status === 'done').length;
    return maxCount === 1 ? doneFileCount === 0 : doneFileCount < maxCount;
  }, [fileList, maxCount]);

  /** 自定义上传项渲染 */
  const renderUploadItem = (originNode: React.ReactNode, file: UploadFile) => {
    const imgUrl = file.response?.data?.fullurl || file.url || '';
    return (
      <div>
        <Image
          width={previewSize}
          height={previewSize}
          src={imgUrl}
          alt={file.name}
          preview={false}
          onClick={() => handlePreview(file)}
        />
        <div>{originNode}</div>
        <div
          onMouseEnter={(e) => {
            const bar = e.currentTarget.querySelector('div') as HTMLElement;
            if (bar) bar.style.opacity = '1';
          }}
          onMouseLeave={(e) => {
            const bar = e.currentTarget.querySelector('div') as HTMLElement;
            if (bar) bar.style.opacity = '0';
          }}
        />
      </div>
    );
  };

  return (
    <>
      <Upload
        fileList={fileList}
        customRequest={customRequest}
        accept={accept}
        listType="picture-card"
        maxCount={maxCount}
        onChange={handleChange}
        onPreview={handlePreview}
        showUploadList={{
          showPreviewIcon: true,
          showRemoveIcon: true,
          showDownloadIcon: false,
        }}
        multiple={maxCount > 1} //maxCount>1自动开启多选，=1关闭多选
      >
        {showUploadBtn && (
          <div>
            <UploadOutlined className="anticon-upload" />
            <div className="ant-upload-text">上传图片</div>
          </div>
        )}
      </Upload>

      {/* 预览弹窗 */}
      <Image
        preview={{
          visible: previewVisible,
          onVisibleChange: setPreviewVisible,
          minScale: 0.5,
          maxScale: 1.4,
          scaleStep: 0.2,
        }}
        src={currentPreviewUrl}
        style={{ display: 'none' }}
      />
    </>
  );
};

export default ImageUploader;